﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Pub;
using System.Data;
using System.IO;
using WORD = System.UInt16;
using DWORD = System.UInt32;
using BYTE = System.Byte;
using ULONGLONG = System.UInt64;
using System.Reflection;
using System.Runtime.InteropServices;

namespace JTBox.Forms.PE
{
    public partial class PEMain : System.Web.UI.Page
    {
        string cmd = "";
        byte[] pe_byte_array;
        int f_Len;
        CPE pe;
        string sJson = "";
        string sTyp = "";
        int i_total = 0;
        int i_Page = 0;
        int i_Rows = 0;
        protected void Page_Load(object sender, EventArgs e)
        {
            CDebug.Send(Request.Url.ToString());
            cmd = Request["cmd"] != null ? Request["cmd"] : "";
            sTyp = Request["typ"] != null ? Request["typ"] : "";
            i_Page = !string.IsNullOrEmpty(Request["page"]) ? Convert.ToInt32(Request["page"]) : 0;
            i_Rows = !string.IsNullOrEmpty(Request["rows"]) ? Convert.ToInt32(Request["rows"]) : 0;
            CDebug.Send("page=" + i_Page + ", rows=" + i_Rows);

            switch (cmd)
            {
                case "getfilelist":
                    getFileList();
                    break;
                case "openpe":
                    openPE();
                    getDosHeader();
                    getFileHeader();
                    getOptionalHeader();
                    getDataDirectory();
                    getSectionHeader();
                    pe_read("13");

                    break;
                case "read":
                    pe_read(sTyp);
                    break;
            }
        }

        protected void getFileList()
        {
            string sU_ID = Session["user_id"] != null ? Session["user_id"].ToString() : "";
            string strSQL = "SELECT * FROM wp_PEinfo WHERE u_ID=" + sU_ID;
            CADO ado1 = new CADO();
            DataSet ds1 = ado1.sel1(strSQL);
            CDebug.Send(strSQL + "\n--返回结果集个数：" + ado1.ds_count);
            string s1 = "";
            if (!CDB.dsIsNull(ds1))
            {
                s1 = "{\"total\":" + ds1.Tables[0].Rows.Count + ",\"rows\":[";
                DataColumnCollection dc1 = ds1.Tables[0].Columns;
                for (int i = 0; i < ds1.Tables[0].Rows.Count;i++ )
                {
                    if (i!=0) s1 +=",";
                    s1 +="{";
                    DataRow dr1 = ds1.Tables[0].Rows[i];
                    for (int j = 0; j < dc1.Count;j++ )
                    {
                        if(j!=0) s1 += ",";
                        s1 += "\"" + dc1[j].Caption.ToLower() + "\":\"" + dr1[j].ToString() + "\"";
                    }
                    s1 += "}";
                }
                s1 += "]}";
            }
            else
            {
                s1 = "{\"total\":0,\"rows\":[";
                s1 += "]}";
            }
            Response.Write(s1);
            Response.End();
        }

        /// <summary>
        /// 打开文件、读入二进制数组
        /// </summary>
        protected void openPE()
        {
            CDebug.EnterMethod("打开pe文件");
            Session["f_id"] = null;
            Session["byte_pe"] = null;
            Session["byte_pe_len"] = null;
            Session["pe"] = null;
            pe = new CPE();

            string f_id = Request["f_id"] != null ? Request["f_id"] : "";
            string typ = Request["typ"] != null ? Request["typ"] : "";
            string strSQL = "SELECT * FROM wp_PEInfo WHERE f_ID=" + f_id;
            CADO ado1 = new CADO();
            DataSet ds1 = ado1.sel1(strSQL);
            CDebug.Send(strSQL + "\n--返回结果个数：" + ado1.ds_count);
            if (!CDB.dsIsNull(ds1))
            {
                string sFileName = Server.MapPath("~") + "temp\\" + ds1.Tables[0].Rows[0]["FileName"].ToString();
                FileStream fs = File.Open(sFileName, FileMode.Open, FileAccess.Read);
                FileInfo fi = new FileInfo(sFileName);
                f_Len = (int)fi.Length;
                pe_byte_array = new byte[f_Len];
                int nBytesRead = fs.Read(pe_byte_array, 0, f_Len);
                //pe_byte_array = ByteArray;
                fs.Close();         //关闭文件

                Session["f_id"] = f_id;
                Session["byte_pe"] = pe_byte_array;
                Session["byte_pe_len"] = f_Len;
                Session["pe"] = pe;
            }
            CDebug.ExitMethod("打开pe文件");
        }

        /// <summary>
        /// 解析pe结构
        /// </summary>
        /// <param name="sTyp"></param>
        private void pe_read(string sTyp)
        {
            if (Session["byte_pe"] != null)
            {
                i_total = 0;
                pe_byte_array = (byte[])Session["byte_pe"];
                f_Len = (int)Session["byte_pe_len"];
                pe = (CPE)Session["pe"];

                switch (Convert.ToInt16(sTyp))
                {
                    case 10:
                        getDosHeader();
                        break;
                    case 11:
                        getFileHeader();
                        getOptionalHeader();
                        break;
                    case 12:
                        getDataDirectory();
                        break;
                    case 13:
                        getSectionHeader();
                        break;
                    case 14:
                        getImportDescriptor();
                        break;
                    case 15:
                        getExportDirectory();
                        break;
                    case 16:
                        getResourceDirectory();
                        break;
                }

                CDebug.Send("记录数量：" + i_total.ToString());
                sJson = "[" + sJson.Replace("'", "\"") + "]";
                sJson = "{\"total\":" + i_total + ",\"rows\":" + sJson + "}";
                CDebug.Send(sJson);
                Response.Write(sJson);
                Response.End();
            }

        }

        /// <summary>
        /// 解析dos头
        /// </summary>
        private void getDosHeader()
        {
            CDebug.EnterMethod("解析Dos头");
            try
            {
                //给DOS头结构体赋值
                CPub.BytesToStuct(pe_byte_array, pe.DOS_HEADER, 0);         //index从0开始
                pe.FILE_HEADER_START = pe.DOS_HEADER.e_lfanew;              //获取pe头开始位置

                int i_index = 0;
                //ListViewGroup lvGroup = new ListViewGroup("MS_DOS HEADER");
                //lv_info.Groups.Add(lvGroup);
                sJson += "{'name':'MS_DOS HEADER','val':'','oth':'',";
                sJson += "'children':[";
                //ListViewItem lvitem = null;
                for (int i = 0; i < pe.DOS_HEADER_TXT.Length; i++)
                {

                    //lvitem = new ListViewItem();
                    //lvitem.Group = lvGroup;
                    //lvitem.Text = pe.DOS_HEADER_TXT[i];
                    string s1 = "";
                    for (int j = 0; j < pe.DOS_HEADER_LEN[i]; j++)
                    {
                        s1 += pe_byte_array[i_index].ToString("X2");
                        i_index++;
                    }
                    //lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));            //每4字节用空格分隔
                    //lvitem.Tag = s1.Trim();
                    //lv_info.Items.Add(lvitem);
                    if (i != 0) sJson += ",";
                    sJson += "{";
                    sJson += "'name':'" + pe.DOS_HEADER_TXT[i] + "','val':'" + CPub.insertStrStepN(s1.Trim(), 4, " ") + "','oth':''";
                    sJson += "}";
                    i_total++;
                }
                sJson += "]";
                sJson += "}";
                i_total++;
                CDebug.Send(Convert.ToString(pe.DOS_HEADER.e_lfanew, 16));
                Session["pe"] = pe;
            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析Dos头");
        }

        /// <summary>
        /// 解析pe头 File_Header部分
        /// </summary>
        private void getFileHeader()
        {
            CDebug.EnterMethod("解析File_Header");
            try
            {

                DWORD i_index = pe.FILE_HEADER_START + 4;   //偏移4字节
                CDebug.Send("File_Header起始位置：" + i_index.ToString("X"));

                //给结构体赋值
                CPub.BytesToStuct(pe_byte_array, pe.FILE_HEADER, (int)(pe.FILE_HEADER_START + 4));
                pe.OPTIONAL_HEADER_START = pe.FILE_HEADER_START + 4 + (DWORD)Marshal.SizeOf(pe.FILE_HEADER);    //Optional_Header起始位置
                //CDebug.Send(pe.FILE_HEADER.Machine.ToString("X"));

                //ListViewGroup lvGroup = new ListViewGroup("FILE HEADER");
                //lv_info.Groups.Add(lvGroup);
                //ListViewItem lvitem = null;
                if (sJson != "") sJson += ",";
                sJson += "{'name':'FILE HEADER','val':'','oth':'',";
                sJson += "'children':[";
                for (int i = 0; i < pe.FILE_HEADER_TXT.Length; i++)
                {
                    //lvitem = new ListViewItem();
                    //lvitem.Group = lvGroup;
                    //lvitem.Text = pe.FILE_HEADER_TXT[i];
                    string s1 = "";
                    for (int j = 0; j < pe.FILE_HEADER_LEN[i]; j++)
                    {
                        s1 += pe_byte_array[i_index].ToString("X2");
                        i_index++;
                    }
                    //lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));        //每4字节用空格分隔
                    //lvitem.Tag = s1.Trim();
                    //lv_info.Items.Add(lvitem);
                    if (i != 0) sJson += ",";
                    sJson += "{";
                    sJson += "'name':'" + pe.FILE_HEADER_TXT[i] + "','val':'" + CPub.insertStrStepN(s1.Trim(), 4, " ") + "','oth':''";
                    sJson += "}";
                    i_total++;
                }
                sJson += "]";
                sJson += "}";
                i_total++;
                Session["pe"] = pe;
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析File_Header");
        }

        /// <summary>
        /// 解析pe头 Optional_Header pe头扩展部分
        /// </summary>
        private void getOptionalHeader()
        {
            CDebug.EnterMethod("解析Optional_Header");
            try
            {
                DWORD i_index = pe.OPTIONAL_HEADER_START;
                CDebug.Send("Optional_Header起始位置：" + i_index.ToString("X"));

                CPub.BytesToStuct(pe_byte_array, pe.OPTIONAL_HEADER, (Int32)pe.OPTIONAL_HEADER_START);
                pe.DATA_DIRECTORY_START = pe.OPTIONAL_HEADER_START + (DWORD)Marshal.SizeOf(pe.OPTIONAL_HEADER);     //Data_Directory起始位置

                //ListViewGroup lvGroup = new ListViewGroup("OPTIONAL HEADER");
                //lv_info.Groups.Add(lvGroup);
                //ListViewItem lvitem = null;
                if (sJson != "") sJson += ",";
                sJson += "{'name':'OPTIONAL HEADER','val':'','oth':'',";
                sJson += "'children':[";
                for (int i = 0; i < pe.OPTIONAL_HEADER_TXT.Length; i++)
                {
                    //lvitem = new ListViewItem();
                    //lvitem.Group = lvGroup;
                    //lvitem.Text = pe.OPTIONAL_HEADER_TXT[i];
                    string s1 = "";
                    for (int j = 0; j < pe.OPTIONAL_HEADER_LEN[i]; j++)
                    {
                        s1 += pe_byte_array[i_index].ToString("X2");
                        i_index++;
                    }
                    //lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));    //每4字节用空格分隔
                    //lvitem.Tag = s1.Trim();
                    //lv_info.Items.Add(lvitem);
                    if (i != 0) sJson += ",";
                    sJson += "{";
                    sJson += "'name':'" + pe.OPTIONAL_HEADER_TXT[i] + "','val':'" + CPub.insertStrStepN(s1.Trim(), 4, " ") + "','oth':''";
                    sJson += "}";
                    i_total++;
                }
                sJson += "]";
                sJson += "}";
                i_total++;
                Session["pe"] = pe;
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析Optional_Header");
        }

        /// <summary>
        /// 解析数据目录
        /// </summary>
        private void getDataDirectory()
        {
            CDebug.EnterMethod("解析数据目录");
            try
            {

                DWORD i_index = pe.DATA_DIRECTORY_START;
                CDebug.Send("数据目录起始位置：" + i_index.ToString("X"));

                //给结构体赋值
                DWORD d_index = pe.DATA_DIRECTORY_START;
                for (int i = 0; i < pe.DATA_DIRECTORY_TIT.Length; i++)
                {
                    pe.DATA_DIRECTORY[i] = new CPE.IMAGE_DATA_DIRECTORY();                  //实例化对象
                    CPub.BytesToStuct(pe_byte_array, pe.DATA_DIRECTORY[i], (Int32)d_index);
                    d_index += (DWORD)Marshal.SizeOf(pe.DATA_DIRECTORY[i]);
                }
                pe.SECTION_HEADER_START = pe.DATA_DIRECTORY_START + (DWORD)pe.DATA_DIRECTORY_TIT.Length * (DWORD)Marshal.SizeOf(pe.DATA_DIRECTORY[0]);   //区块表起始位置
                //CDebug.Send(pe.SECTION_HEADER_START.ToString("X"));

                for (int i = 0; i < pe.DATA_DIRECTORY_TIT.Length; i++)
                {
                    //ListViewGroup lvGroup = new ListViewGroup("DATA DIRECTORY");
                    //lv_info.Groups.Add(lvGroup);
                    //ListViewItem lvitem = null;

                    //lvGroup = new ListViewGroup(pe.DATA_DIRECTORY_TIT[i]);
                    //lv_info.Groups.Add(lvGroup);
                    if (sJson != "") sJson += ",";
                    sJson += "{'name':'" + pe.DATA_DIRECTORY_TIT[i] + "','val':'','oth':'',";
                    sJson += "'children':[";
                    for (int k = 0; k < pe.DATA_DIRECTORY_TXT.Length; k++)
                    {
                        //lvitem = new ListViewItem();
                        //lvitem.Group = lvGroup;
                        //lvitem.Text = pe.DATA_DIRECTORY_TXT[k];
                        string s1 = "";
                        for (int j = 0; j < pe.DATA_DIRECTORY_LEN[k]; j++)
                        {
                            s1 += pe_byte_array[i_index].ToString("X2");
                            i_index++;
                        }
                        s1 = CPub.HexReversal(s1);
                        //lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));    //每4字节用空格分隔
                        //lvitem.SubItems.Add(pe.DATA_DIRECTORY_OTH[k]);                  //数据说明
                        //lvitem.Tag = s1.Trim();
                        //lv_info.Items.Add(lvitem);
                        if (k != 0) sJson += ",";
                        sJson += "{";
                        sJson += "'name':'" + pe.DATA_DIRECTORY_TXT[k] + "','val':'" + CPub.insertStrStepN(s1.Trim(), 4, " ") + "','oth':'" + pe.DATA_DIRECTORY_OTH[k] + "'";
                        sJson += "}";

                        /*
                        if (lvitem.Text == "VirtualAddress")
                        {
                            pe.DATA_DIRECTORY[i].VirtualAddress = Convert.ToUInt32(CPub.HexReversal(s1), 16);
                            //CDebug.Send(Convert.ToString(pe.DATA_DIRECTORY[i].VirtualAddress, 16));
                        }
                        else if (lvitem.Text == "Size")
                        {
                            pe.DATA_DIRECTORY[i].Size = Convert.ToUInt32(CPub.HexReversal(s1), 16);
                            //CDebug.Send(Convert.ToString(pe.DATA_DIRECTORY[i].Size, 16));
                        }
                        */
                    }
                    sJson += "]";
                    sJson += "}";
                }
                Session["pe"] = pe;
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析数据目录");
        }

        /// <summary>
        /// 解析区块表
        /// </summary>
        private void getSectionHeader()
        {
            CDebug.EnterMethod("解析区块表");
            try
            {

                DWORD i_index = pe.SECTION_HEADER_START + 8;    //偏移8字节
                CDebug.Send("SECTION_HEADER 起始位置：" + i_index.ToString("X"));

                DWORD d_index = pe.SECTION_HEADER_START + 8;
                pe.SECTION_HEADER = new CPE._IMAGE_SECTION_HEADER[pe.FILE_HEADER.NumberOfSections];     //实例化区块表数组对象
                for (int i = 0; i < pe.FILE_HEADER.NumberOfSections; i++)
                {
                    //CDebug.Send(i.ToString() + "," + d_index.ToString("X"));
                    pe.SECTION_HEADER[i] = new CPE._IMAGE_SECTION_HEADER();                             //实例化数组元素
                    CPub.BytesToStuct(pe_byte_array, pe.SECTION_HEADER[i], (Int32)d_index);
                    d_index += (DWORD)Marshal.SizeOf(pe.SECTION_HEADER[i]);
                }

                //ListViewGroup lvGroup = new ListViewGroup("SECTION_HEADER");
                //lv_info.Groups.Add(lvGroup);
                //ListViewItem lvitem = null;

                for (int i = 0; i < pe.FILE_HEADER.NumberOfSections; i++)
                {
                    for (int k = 0; k < pe.SECTION_HEADER_TXT.Length; k++)
                    {
                        //lvitem = new ListViewItem();
                        //lvitem.Text = pe.SECTION_HEADER_TXT[k];
                        string s1 = "";         //区段名称、最大长度为8个字节
                        string s_name = "";
                        bool b_end = false;     //区段名是否结束
                        for (int j = 0; j < pe.SECTION_HEADER_LEN[k]; j++)
                        {
                            if (pe_byte_array[i_index] == 0) b_end = true;                              //字符串结束
                            if (k == 0 && !b_end) s_name += Convert.ToChar(pe_byte_array[i_index]);     //name 显示字符串 循环到结尾位置、直接退出
                            s1 += pe_byte_array[i_index].ToString("X2");
                            i_index++;
                        }
                        if (k == 0)
                        {
                            //lvGroup = new ListViewGroup(s_name);
                            //lv_info.Groups.Add(lvGroup);
                            if (sJson != "") sJson += ",";
                            sJson += "{'name':'" + s_name + "','val':'','oth':'',";
                            sJson += "'children':[";
                        }
                        //lvitem.Group = lvGroup;
                        if (k != 0) s1 = CPub.HexReversal(s1);                                                  //反转字符串
                        //lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));                            //每4字节用空格分隔
                        string sOth = pe.SECTION_HEADER_OTH[k];                                                 //说明
                        if (k == 0) sOth = s_name + "  " + sOth;                                               //说明 显示字符串
                        //lvitem.SubItems.Add(sOth);                                                              //结构体说明
                        //lvitem.Tag = s1.Trim();
                        //lv_info.Items.Add(lvitem);
                        if (k != 0) sJson += ",";
                        sJson += "{";
                        sJson += "'name':'" + pe.SECTION_HEADER_TXT[k] + "','val':'" + CPub.insertStrStepN(s1.Trim(), 4, " ") + "','oth':'" + sOth + "'";
                        sJson += "}";
                    }
                    sJson += "]";
                    sJson += "}";
                }

                //pe.DATA_DIRECTORY_START = Convert.ToString(i_index, 16);         // 起始位置
                Session["pe"] = pe;
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析区块表");
        }

        /// <summary>
        /// 解析输入表
        /// </summary>
        private void getImportDescriptor()
        {
            CDebug.EnterMethod("解析输入表");
            try
            {
                //tv_info.Nodes.Clear();

                pe.IMPORT_DESCRIPTOR_START = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;     //输入表起始位置
                DWORD l1 = pe.IMPORT_DESCRIPTOR_START;
                if (l1 == 0)
                {
                    CDebug.Send("没有输入表");
                    CDebug.ExitMethod("解析输入表");
                    return;
                }
                DWORD dw_offset = 0;       //在文件中的偏移
                for (int i = pe.FILE_HEADER.NumberOfSections - 1; i >= 0; i--)
                {
                    if (l1 >= pe.SECTION_HEADER[i].VirtualAddress)      //查找输入表所在区块，输入表起始位置大于等于区块起始位置，小于下一区块起始位置
                    {
                        dw_offset = pe.SECTION_HEADER[i].VirtualAddress - pe.SECTION_HEADER[i].PointerToRawData;   //计算偏移地址
                        CDebug.Send("i=" + i.ToString() + ": " + Convert.ToString(pe.SECTION_HEADER[i].VirtualAddress, 16) + "-"
                            + Convert.ToString(pe.SECTION_HEADER[i].PointerToRawData, 16) + "=" + Convert.ToString(dw_offset, 16)
                            + ", SIZE=" + Convert.ToString(pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].Size, 16));
                        break;
                    }
                }
                DWORD i_index = l1 - dw_offset;                                                                     //计算偏移地址
                CDebug.Send("输入表起始位置：" + l1.ToString("X") + "-" + dw_offset.ToString("X") + "=" + i_index.ToString("X"));

                #region 给结构体赋值
                DWORD i_end = i_index + pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
                DWORD d_index = l1 - dw_offset;
                DWORD i_count = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_IMPORT].Size / (DWORD)Marshal.SizeOf(new CPE._IMAGE_IMPORT_DESCRIPTOR());
                CDebug.Send("结构体个数：" + i_count);
                pe.IMPORT_DESCRIPTOR = new CPE._IMAGE_IMPORT_DESCRIPTOR[i_count];
                for (int i = 0; i < i_count; i++)
                {
                    pe.IMPORT_DESCRIPTOR[i] = new CPE._IMAGE_IMPORT_DESCRIPTOR();
                    CPub.BytesToStuct(pe_byte_array, pe.IMPORT_DESCRIPTOR[i], (Int32)d_index);
                    d_index += (DWORD)Marshal.SizeOf(pe.IMPORT_DESCRIPTOR[i]);
                }
                #endregion

                /*
                //通过反射遍历结构体
                for (int i = 0; i < i_count; i++)
                {
                    Type type = typeof(CPE._IMAGE_IMPORT_DESCRIPTOR);
                    foreach (FieldInfo mi in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                    {
                        Object Value = mi.GetValue(pe.IMPORT_DESCRIPTOR[i]);
                        CDebug.Send(mi.Name + "=" + Convert.ToString((DWORD)Value, 16) + ",type=" + mi.FieldType.Name);
                        
                    }
                }
                */

                #region 树目录显示
                //if (tv_info.Visible)
                {
                    string s2 = "";
                    for (int i = 0; i < pe.IMPORT_DESCRIPTOR.Length; i++)
                    {
                        s2 = "";
                        TreeNode node1 = new TreeNode();
                        //解析dll名称
                        long l4 = pe.IMPORT_DESCRIPTOR[i].Name;
                        if (l4 != 0)
                        {
                            long l3 = l4 - dw_offset;                              //通过偏移计算字符串位置
                            //CDebug.Send(Convert.ToString(l4, 16) + "-" + Convert.ToString(l2, 16) + "=" + Convert.ToString(l3, 16));
                            while (l3 < f_Len && l3 > 0 && pe_byte_array[l3] != 0)
                            {
                                s2 += Convert.ToChar(pe_byte_array[l3]);
                                l3++;
                            }
                            node1.Text = s2;
                            if (sJson != "") sJson += ",";
                            sJson += "{'name':'" + s2 + "','val':'','oth':'','state':'closed',";
                            sJson += "'children':[";
                        }
                        else
                        {
                            if (s2 == "") break;        //dll名为空，停止解析
                        }

                        if (pe.IMPORT_DESCRIPTOR[i].OriginalFirstThunk != 0)
                        {
                            DWORD d_index2 = pe.IMPORT_DESCRIPTOR[i].OriginalFirstThunk - dw_offset;
                            CPE._IMAGE_THUNK_DATA32 THUNK_DATA = new CPE._IMAGE_THUNK_DATA32();
                            CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);
                            while (THUNK_DATA.AddressOfData != 0)
                            {
                                //最高位第32位为0时显示函数名，为1时为序号输入
                                if (THUNK_DATA.AddressOfData >> 31 == 0)
                                {
                                    DWORD d_name_adr = THUNK_DATA.AddressOfData - dw_offset;
                                    if (d_name_adr > 0 && d_name_adr < f_Len)   //下标是否越界
                                    {
                                        //Hint 函数在驻留dll的输出表中的序号
                                        string s3 = pe_byte_array[d_name_adr].ToString("X2");
                                        d_name_adr++;
                                        s3 += pe_byte_array[d_name_adr].ToString("X2");
                                        d_name_adr++;

                                        string s4 = "";
                                        while (pe_byte_array[d_name_adr] != 0)
                                        {
                                            s4 += Convert.ToChar(pe_byte_array[d_name_adr]);
                                            d_name_adr++;
                                        }
                                        TreeNode node2 = new TreeNode();
                                        node2.Text = "[" + s3 + "] " + s4;  //函数名称
                                        //****//node1.Nodes.Add(node2);
                                        //if (k != 0) sJson += ",";
                                        sJson += "{";
                                        sJson += "'name':'" + s3 + "','val':'" + s4 + "','oth':''";
                                        sJson += "},";
                                    }
                                }
                                else
                                {
                                    //低31位为序号
                                    DWORD d_name_adr = THUNK_DATA.AddressOfData - dw_offset - 0x80000000;

                                    TreeNode node2 = new TreeNode();
                                    node2.Text = "[-] 序号：" + d_name_adr.ToString("X4");  //函数序号
                                    //****//node1.Nodes.Add(node2);
                                    //if (k != 0) sJson += ",";
                                    sJson += "{";
                                    sJson += "'name':'[-]','val':'" + d_name_adr.ToString("X4") + "','oth':''";
                                    sJson += "},";
                                }


                                d_index2 += 4;
                                CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);
                            }
                        }

                        if (pe.IMPORT_DESCRIPTOR[i].FirstThunk != 0)
                        {
                            DWORD d_index2 = pe.IMPORT_DESCRIPTOR[i].FirstThunk - dw_offset;
                            CPE._IMAGE_THUNK_DATA32 THUNK_DATA = new CPE._IMAGE_THUNK_DATA32();
                            CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);
                            while (THUNK_DATA.AddressOfData != 0)
                            {
                                DWORD d_name_adr = THUNK_DATA.AddressOfData - dw_offset;
                                string s3 = "";
                                string s4 = "";
                                if (d_name_adr > 0 && d_name_adr < f_Len)   //下标越界
                                {
                                    //Hint 函数在驻留dll的输出表中的序号
                                    s3 = pe_byte_array[d_name_adr].ToString("X2");
                                    d_name_adr++;
                                    s3 += pe_byte_array[d_name_adr].ToString("X2");
                                    d_name_adr++;

                                    while (pe_byte_array[d_name_adr] != 0)
                                    {
                                        s4 += Convert.ToChar(pe_byte_array[d_name_adr]);
                                        d_name_adr++;
                                    }
                                    TreeNode node2 = new TreeNode();
                                    node2.Text = "[" + s3 + "] " + s4; //函数名称
                                    Boolean b_name = false;
                                    foreach (TreeNode node_temp in node1.ChildNodes)
                                    {
                                        if (node2.Text == node_temp.Text)
                                        {
                                            b_name = true;
                                            break;
                                        }
                                    }
                                    //****//if (!b_name) node1.Nodes.Add(node2);
                                    //if (k != 0) sJson += ",";
                                    if (!b_name)
                                    {
                                        sJson += "{";
                                        sJson += "'name':'" + s3 + "','val':'" + s4 + "','oth':''";
                                        sJson += "},";
                                    }
                                }

                                d_index2 += 4;
                                CPub.BytesToStuct(pe_byte_array, THUNK_DATA, (Int32)d_index2);
                            }
                        }
                        //tv_info.Nodes.Add(node1);
                        sJson.Remove(sJson.Length - 1, 1);
                        sJson += "]";
                        sJson += "}";
                    }
                }
                #endregion

                #region 列表显示
                //if (lv_info.Visible)
                {
                    //ListViewGroup lvGroup = new ListViewGroup("Import Descriptor");
                    //lv_info.Groups.Add(lvGroup);
                    //ListViewItem lvitem = null;

                    int i_No = 0;
                    while (i_index < i_end)
                    {
                        string s1 = "";
                        string s2 = "";
                        for (int k = 0; k < pe.IMPORT_DESCRIPTOR_TXT.Length; k++)
                        {
                            //lvitem = new ListViewItem();
                            //lvitem.Text = pe.IMPORT_DESCRIPTOR_TXT[k];
                            s1 = "";
                            for (int j = 0; j < pe.IMPORT_DESCRIPTOR_LEN[k]; j++)
                            {
                                //if (k == 0) s2 += Convert.ToChar(pe_byte_array[i_index]);         //name 显示字符串
                                s1 += pe_byte_array[i_index].ToString("X2");
                                i_index++;
                            }

                            //lvitem.Group = lvGroup;
                            //lvitem.SubItems.Add(CPub.insertStrStepN(s1.Trim(), 4, " "));            //每4字节用空格分隔                        
                            if (k == 0)
                            {
                                i_No++;
                                //lvitem.SubItems.Add(i_No.ToString());                               //序号
                            }
                            //给对象赋值
                            switch (pe.IMPORT_DESCRIPTOR_TXT[k])
                            {
                                case "Name":                                              //dll名称
                                    #region 解析dll名称
                                    try
                                    {
                                        long l4 = pe.IMPORT_DESCRIPTOR[i_No - 1].Name;
                                        if (l4 != 0)
                                        {
                                            long l3 = l4 - dw_offset;                              //通过偏移计算字符串位置
                                            //CDebug.Send(Convert.ToString(l4, 16) + "-" + Convert.ToString(l2, 16) + "=" + Convert.ToString(l3, 16));
                                            while (l3 < f_Len && l3 > 0 && pe_byte_array[l3] != 0)
                                            {
                                                s2 += Convert.ToChar(pe_byte_array[l3]);
                                                l3++;
                                            }
                                            //lvitem.SubItems.Add(s2);
                                        }
                                        else
                                        {
                                            if (s2 == "") break;        //dll名为空，停止解析
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        CDebug.SendError(ex.ToString());
                                    }
                                    #endregion
                                    break;
                            }

                            //lvitem.Tag = s1.Trim();
                            //lv_info.Items.Add(lvitem);

                        }

                        if (s2 == "") break;
                    }
                }
                #endregion
                //pe.DATA_DIRECTORY_START = Convert.ToString(i_index, 16);                      // 起始位置
                Session["pe"] = pe;
            }
            catch (Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析输入表");
        }

        /// <summary>
        /// 解析输出表
        /// </summary>
        private void getExportDirectory()
        {
            CDebug.EnterMethod("解析输出表");
            try
            {
                //tv_info.Nodes.Clear();

                pe.EXPORT_DIRECTORY_START = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;     //输出表起始位置
                DWORD l1 = pe.EXPORT_DIRECTORY_START;
                if (l1 == 0)
                {
                    CDebug.Send("没有输出表");
                    CDebug.ExitMethod("解析输出表");
                    return;
                }
                DWORD dw_offset = 0;       //在文件中的偏移
                for (int i = pe.FILE_HEADER.NumberOfSections - 1; i >= 0; i--)
                {
                    if (l1 >= pe.SECTION_HEADER[i].VirtualAddress)      //查找输入表所在区块，输入表起始位置大于等于区块起始位置，小于下一区块起始位置
                    {
                        dw_offset = pe.SECTION_HEADER[i].VirtualAddress - pe.SECTION_HEADER[i].PointerToRawData;   //计算偏移地址
                        CDebug.Send("i=" + i.ToString() + ": " + Convert.ToString(pe.SECTION_HEADER[i].VirtualAddress, 16) + "-"
                            + Convert.ToString(pe.SECTION_HEADER[i].PointerToRawData, 16) + "=" + Convert.ToString(dw_offset, 16)
                            + ", SIZE=" + Convert.ToString(pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].Size, 16));
                        break;
                    }
                }
                DWORD i_index = l1 - dw_offset;                                                                     //计算偏移地址
                CDebug.Send("输出表起始位置：" + l1.ToString("X") + "-" + dw_offset.ToString("X") + "=" + i_index.ToString("X"));

                #region 给结构体赋值
                DWORD i_end = i_index + pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
                DWORD d_index = l1 - dw_offset;
                DWORD i_count = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_EXPORT].Size / (DWORD)Marshal.SizeOf(new CPE._IMAGE_EXPORT_DIRECTORY());
                CDebug.Send("数量：" + i_count);
                CPub.BytesToStuct(pe_byte_array, pe.EXPORT_DIRECTORY, (Int32)d_index);
                d_index += (DWORD)Marshal.SizeOf(pe.EXPORT_DIRECTORY);

                #endregion

                #region 树目录显示
                //if (tv_info.Visible)
                {
                    //tv_info.Nodes.Clear();

                    TreeNode node1 = new TreeNode();
                    string sDllName = "";
                    DWORD d_index2 = pe.EXPORT_DIRECTORY.Name - dw_offset;
                    while (d_index2 > 0 && d_index2 < f_Len && pe_byte_array[d_index2] != 0)
                    {
                        sDllName += Convert.ToChar(pe_byte_array[d_index2]);
                        d_index2++;
                    }
                    node1.Text = sDllName;

                    Int32 i_fun_count = (Int32)pe.EXPORT_DIRECTORY.NumberOfFunctions;    //EAT条码数量
                    Int32 i_nam_count = (Int32)pe.EXPORT_DIRECTORY.NumberOfNames;        //ENT条码数量
                    string[] sFun = new string[i_fun_count];
                    string[] sNam = new string[i_nam_count];
                    string[] s_Index = new string[i_nam_count];

                    d_index2 = pe.EXPORT_DIRECTORY.AddressOfFunctions - dw_offset;
                    CDebug.Send("函数数量：" + i_fun_count + " 地址：" + d_index2.ToString("X"));
                    for (int j = 0; j < i_fun_count; j++)
                    {
                        TreeNode node2 = new TreeNode();
                        for (int k = 0; k < 4; k++)
                        {
                            sFun[j] += pe_byte_array[d_index2].ToString("X2");
                            d_index2++;
                        }
                        sFun[j] = CPub.HexReversal(sFun[j]);        //反转16进制

                        node2.Text = "[" + sFun[j] + "]";
                        //****//node1.Nodes.Add(node2);
                    }

                    d_index2 = pe.EXPORT_DIRECTORY.AddressOfNames - dw_offset;
                    CDebug.Send("函数名称数量：" + i_nam_count + " 地址：" + d_index2.ToString("X"));
                    for (int j = 0; j < i_nam_count; j++)
                    {
                        string s1 = "";
                        for (int k = 0; k < 4; k++)
                        {
                            s1 += pe_byte_array[d_index2].ToString("X2");
                            d_index2++;
                        }
                        s1 = CPub.HexReversal(s1);              //反转16进制

                        DWORD dw1 = Convert.ToUInt32(s1, 16) - dw_offset;   //函数名存放地址

                        while (dw1 > 0 && dw1 < f_Len && pe_byte_array[dw1] != 0)
                        {
                            sNam[j] += Convert.ToChar(pe_byte_array[dw1]);
                            dw1++;
                        }
                        //CDebug.Send(j.ToString() + ": " + sNam[j]);
                    }

                    //函数与名称对应关系
                    d_index2 = pe.EXPORT_DIRECTORY.AddressOfNameOrdinals - dw_offset;
                    CDebug.Send("序号数组地址：" + d_index2.ToString("X"));
                    for (int j = 0; j < i_nam_count; j++)
                    {
                        for (int k = 0; k < 2; k++)
                        {
                            s_Index[j] += pe_byte_array[d_index2].ToString("X2");
                            d_index2++;
                        }
                        s_Index[j] = CPub.HexReversal(s_Index[j]);              //反转16进制

                        DWORD dw1 = Convert.ToUInt32(s_Index[j], 16);
                        //****//if (node1.Nodes.Count > dw1) node1.Nodes[(Int32)dw1].Text += " " + sNam[j];
                    }

                    //tv_info.Nodes.Add(node1);
                }
                #endregion
                Session["pe"] = pe;
            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析输出表");
        }

        /// <summary>
        /// 解析资源
        /// </summary>
        private void getResourceDirectory()
        {
            CDebug.EnterMethod("解析资源");
            try
            {
                //tv_info.Nodes.Clear();
                pe.RESOURCE_DIRECTORY_START = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;     //资源起始位置
                DWORD l1 = pe.RESOURCE_DIRECTORY_START;
                if (l1 == 0)
                {
                    CDebug.Send("没有资源");
                    CDebug.ExitMethod("解析资源");
                    return;
                }
                DWORD dw_offset = 0;       //在文件中的偏移
                for (int i = pe.FILE_HEADER.NumberOfSections - 1; i >= 0; i--)
                {
                    if (l1 >= pe.SECTION_HEADER[i].VirtualAddress)      //查找输入表所在区块，输入表起始位置大于等于区块起始位置，小于下一区块起始位置
                    {
                        dw_offset = pe.SECTION_HEADER[i].VirtualAddress - pe.SECTION_HEADER[i].PointerToRawData;   //计算偏移地址
                        CDebug.Send("i=" + i.ToString() + ": " + Convert.ToString(pe.SECTION_HEADER[i].VirtualAddress, 16) + "-"
                            + Convert.ToString(pe.SECTION_HEADER[i].PointerToRawData, 16) + "=" + Convert.ToString(dw_offset, 16)
                            + ", SIZE=" + Convert.ToString(pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].Size, 16));
                        break;
                    }
                }
                DWORD i_index = l1 - dw_offset;                                                                     //计算偏移地址
                CDebug.Send("资源起始位置：" + l1.ToString("X") + "-" + dw_offset.ToString("X") + "=" + i_index.ToString("X"));

                #region 给结构体赋值
                DWORD i_end = i_index + pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
                DWORD d_index = l1 - dw_offset; //偏移

                //资源开始位置
                //getRes(tv_info, d_index, 1, dw_offset);

                #endregion

                Session["pe"] = pe;
            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            CDebug.ExitMethod("解析资源");
        }

        /// <summary>
        /// 递归解析资源目录及资源
        /// </summary>
        /// <param name="node1">treeview or treenode</param>
        /// <param name="i_start">起始地址</param>
        /// <param name="i_Level">目录层数</param>
        /// <param name="dw_offset">偏移</param>
        private void getRes(object node1, DWORD i_start, int i_Level, DWORD dw_offset)
        {
            //CDebug.EnterMethod("解析资源");
            try
            {
                //资源开始位置
                DWORD dw_res_start = pe.DATA_DIRECTORY[CPE.IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
                CPE._IMAGE_RESOURCE_DIRECTORY res1 = new CPE._IMAGE_RESOURCE_DIRECTORY();
                CPub.BytesToStuct(pe_byte_array, res1, (Int32)i_start);
                i_start += (DWORD)Marshal.SizeOf(res1);
                int i_count = res1.NumberOfIdEntries + res1.NumberOfNamedEntries; //使用名字的资源条目的个数 + 使用ID的资源条目的个数
                //CDebug.Send("下一级节点个数：" + i_count);
                for (int i = 0; i < i_count; i++)
                {
                    //CDebug.Send("地址：" + i_start.ToString("X"));
                    CPE._IMAGE_RESOURCE_DIRECTORY_ENTRY res_entry1 = new CPE._IMAGE_RESOURCE_DIRECTORY_ENTRY();
                    CPub.BytesToStuct(pe_byte_array, res_entry1, (Int32)i_start);
                    i_start += (DWORD)Marshal.SizeOf(res_entry1);                      //下一个结构体起始位置

                    //CDebug.Send(res_enter1.Name.ToString("X"));
                    TreeNode node2 = new TreeNode();
                    if (i_Level == 1)       //第一层为资源类型
                    {
                        if (res_entry1.Name >> 31 == 1)
                        {
                            node2.Text = (res_entry1.Name - 0x80000000).ToString(); //显示ID
                        }
                        else
                        {
                            if (res_entry1.Name < pe.RESOURCE_DIRECTORY_CAPTION.Length)
                                node2.Text = pe.RESOURCE_DIRECTORY_CAPTION[res_entry1.Name];
                            else
                                node2.Text = res_entry1.Name.ToString();
                        }

                        if (res_entry1.OffsetToData >> 31 == 1)
                        {
                            //指向下一级节点
                            DWORD i_start2 = dw_res_start + res_entry1.OffsetToData - 0x80000000 - dw_offset;  //指向下一层目录起始地址 
                            //CDebug.Send("下一级目录起始地址：" + i_start2.ToString("X"));
                            getRes(node2, i_start2, 2, dw_offset);
                        }
                        else
                        {
                            //指向Image_resource_directory_entry结构
                            DWORD i_start2 = dw_res_start + res_entry1.OffsetToData - dw_offset;  //指向下一层目录起始地址 
                            CPE._IMAGE_RESOURCE_DATA_ENTRY res_data = new CPE._IMAGE_RESOURCE_DATA_ENTRY();
                            CPub.BytesToStuct(pe_byte_array, res_data, (Int32)i_start2);
                            node2.Text += "[RAV:" + res_data.OffsetToData.ToString("X") + "]"
                                + "[OFFSET:" + (res_data.OffsetToData - dw_offset).ToString("X") + "]"
                                + "[SIZE:" + res_data.Size.ToString("X") + "]";
                        }
                    }
                    else if (i_Level == 2)  //第二层为资源名称
                    {
                        DWORD i_start2 = 0;
                        if (res_entry1.Name >> 31 == 1)
                        {
                            i_start2 = dw_res_start + res_entry1.Name - 0x80000000 - dw_offset;    //减去第一位
                            if (i_start2 > 0 && i_start2 < f_Len)
                            {
                                CPE._IMAGE_RESOURCE_DIR_STRING_U strU = new CPE._IMAGE_RESOURCE_DIR_STRING_U();
                                string s1 = pe_byte_array[i_start2].ToString("X2") + pe_byte_array[i_start2 + 1].ToString("X2");
                                i_start2++;
                                i_start2++;
                                s1 = CPub.HexReversal(s1);
                                strU.Length = Convert.ToUInt16(s1, 16);

                                //char[] cpara = System.Text.Encoding.Default.GetChars(pe_byte_array);    //byte[]转char[]
                                //string s2 = new string(cpara, (Int32)i_start2, strU.Length);
                                string s2 = "";
                                //次代码需要改写 System.Text.Encoding.Default.GetString(byte[] bytes)
                                for (int j = 0; j < strU.Length; j++)
                                {
                                    s2 += Convert.ToChar(pe_byte_array[j * 2 + i_start2]);
                                }

                                strU.NameString = s2;
                                node2.Text = s2;
                            }

                        }
                        else
                        {
                            node2.Text = res_entry1.Name.ToString();
                        }

                        if (res_entry1.OffsetToData >> 31 == 1) //还有下一层
                        {
                            //指向下一级节点
                            i_start2 = dw_res_start + res_entry1.OffsetToData - 0x80000000 - dw_offset;  //指向下一层目录起始地址 
                            //CDebug.Send("下一级目录起始地址：" + i_start2.ToString("X"));
                            getRes(node2, i_start2, 3, dw_offset);
                        }
                        else
                        {
                            //指向Image_resource_directory_entry结构
                            i_start2 = dw_res_start + res_entry1.OffsetToData - dw_offset;  //指向下一层目录起始地址 
                            CPE._IMAGE_RESOURCE_DATA_ENTRY res_data = new CPE._IMAGE_RESOURCE_DATA_ENTRY();
                            CPub.BytesToStuct(pe_byte_array, res_data, (Int32)i_start2);
                            node2.Text += "[RAV:" + res_data.OffsetToData.ToString("X") + "]"
                                + "[OFFSET:" + (res_data.OffsetToData - dw_offset).ToString("X") + "]"
                                + "[SIZE:" + res_data.Size.ToString("X") + "]";
                        }

                    }
                    else if (i_Level == 3)   //第三层为代码页编号
                    {
                        DWORD i_start2 = 0;
                        if (res_entry1.Name >> 31 == 1)
                        {
                            i_start2 = dw_res_start + res_entry1.Name - 0x80000000 - dw_offset;    //减去第一位
                            if (i_start2 > 0 && i_start2 < f_Len)
                            {
                                CPE._IMAGE_RESOURCE_DIR_STRING_U strU = new CPE._IMAGE_RESOURCE_DIR_STRING_U();
                                string s1 = pe_byte_array[i_start2].ToString("X2") + pe_byte_array[i_start2 + 1].ToString("X2");
                                i_start2++;
                                i_start2++;
                                s1 = CPub.HexReversal(s1);
                                strU.Length = Convert.ToUInt16(s1, 16);

                                //char[] cpara = System.Text.Encoding.Default.GetChars(pe_byte_array);    //byte[]转char[]
                                //string s2 = new string(cpara, (Int32)i_start2, strU.Length);
                                string s2 = "";
                                for (int j = 0; j < strU.Length; j++)
                                {
                                    s2 += Convert.ToChar(pe_byte_array[j * 2 + i_start2]);
                                }

                                strU.NameString = s2;
                                node2.Text = s2;
                            }

                        }
                        else
                        {
                            node2.Text = res_entry1.Name.ToString();
                        }

                        if (res_entry1.OffsetToData >> 31 == 1) //还有下一层
                        {
                            //指向下一级节点
                            i_start2 = dw_res_start + res_entry1.OffsetToData - 0x80000000 - dw_offset;  //指向下一层目录起始地址 
                            CDebug.Send("下一级目录起始地址：" + i_start2.ToString("X"));
                            getRes(node2, i_start2, 4, dw_offset);
                        }
                        else
                        {
                            //指向Image_resource_directory_entry结构
                            i_start2 = dw_res_start + res_entry1.OffsetToData - dw_offset;  //指向下一层目录起始地址 
                            CPE._IMAGE_RESOURCE_DATA_ENTRY res_data = new CPE._IMAGE_RESOURCE_DATA_ENTRY();
                            CPub.BytesToStuct(pe_byte_array, res_data, (Int32)i_start2);
                            node2.Text += "[RAV:" + res_data.OffsetToData.ToString("X") + "]"
                                + "[OFFSET:" + (res_data.OffsetToData - dw_offset).ToString("X") + "]"
                                + "[SIZE:" + res_data.Size.ToString("X") + "]";
                        }
                    }

                    if (node1 is TreeView) ((TreeView)node1).Nodes.Add(node2);
                    //****//if (node1 is TreeNode) ((TreeNode)node1).Nodes.Add(node2);
                }
            }
            catch (System.Exception ex)
            {
                CDebug.SendError(ex.ToString());
            }
            //CDebug.ExitMethod("解析资源");
        }

    }
}